package org.todo.controller;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletException;
import javax.portlet.PortletRequest;

import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.validation.BindException;
import org.springframework.web.portlet.bind.PortletRequestDataBinder;
import org.springframework.web.portlet.bind.PortletRequestUtils;
import org.springframework.web.portlet.mvc.SimpleFormController;
import org.todo.domain.Category;
import org.todo.domain.Todo;
import org.todo.service.CategoryService;
import org.todo.service.TodoService;

/**
 * Controller that handles the add and edit action requests for todo items
 * @author Matthias Braunhofer
 */
public class EditTodoController extends SimpleFormController {
    //injected dependencies
    private TodoService todoService;
    private CategoryService categoryService;
   
    
    public EditTodoController() {
        setCommandClass(Todo.class);
    }

    /**
     * Prepares a Todo object to be bound to the todo form
     * @param request
     * @return
     * @throws java.lang.Exception
     */
    @Override
    protected Object formBackingObject(PortletRequest request) throws Exception {
        int todoId = PortletRequestUtils.getIntParameter(request, "todoId", -1);

        Todo todo = null;
        if (todoId < 0) {
            Category category = null;
            int categoryId = PortletRequestUtils.getIntParameter(request, "categoryId", -1);

            if (categoryId < 0) {
                category = new Category();
            } else {
                 category = categoryService.getCategory(categoryId);
            }
            
            todo = new Todo();
            todo.setCategory(category);
            todo.setCreationDate(new Date());
            todo.setOwner(ControllerUtil.getUserName(request));
            todo.setOwnerScreenName(ControllerUtil.getUserScreenName(todo.getOwner()));
        } else {
            todo = todoService.getTodo(todoId);
        }

        if(todo == null) {
            throw new PortletException("Todo not found");
        }

        return todo;
    }

    /**
     * Register custom binders for the date and category properties of a todo item
     * @param request
     * @param binder
     * @throws java.lang.Exception
     */
    @Override
    protected void initBinder(PortletRequest request, PortletRequestDataBinder binder) throws Exception {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        df.setLenient(false);
        binder.registerCustomEditor(Date.class, new CustomDateEditor(df, true));
        binder.registerCustomEditor(Category.class, new CustomCategoryEditor());
    }

    /**
     * Provides further data (i.e. all categories for a certain user) to be displayed in the todo form
     * @param request
     * @return
     * @throws java.lang.Exception
     */
    @Override
    protected Map referenceData(PortletRequest request) throws Exception {
        String username = ControllerUtil.getUserName(request);
        List<Category> categories = categoryService.getCategories(username);

        Map map = new HashMap();
        map.put("categories", categories);

        return map;
    }

    /**
     * Action handler method that handles the submit action of the todo form
     * @param request
     * @param response
     * @param command
     * @param bindException
     * @throws java.lang.Exception
     */
    @Override
    protected void onSubmitAction(ActionRequest request, ActionResponse response, Object command, BindException bindException) throws Exception {
        Todo todo = (Todo) command;
        todo.setCategory(categoryService.getCategory(todo.getCategory().getId()));

        todoService.addTodo(todo);

        //map rendering phase to todosController
        response.setRenderParameter("action", "todos");
    }
  
    public void setTodoService(TodoService todoService) {
        this.todoService = todoService;
    }

    public void setCategoryService(CategoryService categoryService) {
        this.categoryService = categoryService;
    }
}
